﻿using Microsoft.Xna.Framework;
using GameLibrary;
using Rescue_of_the_Dwarvenzombies.SceneObjects;

namespace Rescue_of_the_Dwarvenzombies.Rendering
{
    /// <summary>
    /// The animation manager is responsible for handling the sprite animations. It updates the source rectangles
    /// of the scene objects depending on their actions. The animation manager also makes sure that the scene objects
    /// pixel data are up to date.
    /// </summary>
    public class AnimationManager
    {
        /// <summary>
        /// Reference to the Game
        /// </summary>
        private Game _game;

        /// <summary>
        /// Initializes a new instance of the <see cref="AnimationManager"/> class.
        /// </summary>
        /// <param name="game">The game.</param>
        public AnimationManager(Game game)
        {
            _game = game;
        }

        /// <summary>
        /// Updates the source rectangle and pixel data of the scene object passed.
        /// </summary>
        /// <param name="sceneObject">The scene object to be updated.</param>
        internal void CheckSourceRectangle(ISceneObject sceneObject)
        {
            IRenderManager renderManager = (IRenderManager)_game.Services.GetService(typeof(IRenderManager));

            //If the scene object is static, no need to update source rectangle and pixel data
            if (typeof(IStatic).IsAssignableFrom(sceneObject.GetType()))
                return;

            Constant.Action wantedAction = sceneObject.WantedAction;
            Constant.Direction direction = sceneObject.Direction;
            Rectangle sourceRectangle = sceneObject.SourceRectangle;

            //Switch on the object's direction to decide correct animation
            switch (direction)
            {
                case Constant.Direction.Down:
                    sourceRectangle.Y = 0;
                    break;
                case Constant.Direction.Up:
                    sourceRectangle.Y = (sceneObject.RectangleHeight + sceneObject.RectangleOffsetY) * 2;
                    break;
                case Constant.Direction.Right:
                case Constant.Direction.UpRight:
                case Constant.Direction.DownRight:
                    sourceRectangle.Y = (sceneObject.RectangleHeight + sceneObject.RectangleOffsetY);
                    break;
                case Constant.Direction.Left:
                case Constant.Direction.UpLeft:
                case Constant.Direction.DownLeft:
                    sourceRectangle.Y = (sceneObject.RectangleHeight + sceneObject.RectangleOffsetY) * 3;
                    break;
            }

            //If the wanted move is the same as before
            if (sceneObject.PreviousAction == wantedAction)
            {
                //Move the source rectangle for the animation to flow. If out of bounds, start over.
                if (sourceRectangle.X >= sceneObject.TotalTextureWidth - (sceneObject.RectangleWidth + sceneObject.RectangleOffsetX))
                {
                    sourceRectangle.X = 0;
                }
                else
                    sourceRectangle.X += sceneObject.RectangleWidth + sceneObject.RectangleOffsetX;
            }
            //Else start over from the left
            else
                sourceRectangle.X = 0;

            //If the object has moved, store the action
            if (wantedAction != Constant.Action.DoNothing && wantedAction != Constant.Action.Attack)
                sceneObject.PreviousAction = wantedAction;

            //Store the current source rectangle
            sceneObject.SourceRectangle = sourceRectangle;

            //Get the pixel data for the corresponding texture and current animation (source rectangle)
            sceneObject.PixelData = renderManager.PixelDataDictionary[sceneObject.TextureName][sceneObject.SourceRectangle];
        }
    }
}